package com.oa.ht.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.mdp.core.service.BaseService;
import com.mdp.safe.client.entity.User;
import com.mdp.safe.client.utils.LoginUtils;
import com.oa.ht.entity.ContractCondition;
import com.oa.ht.entity.ContractConditionBatchVo;
import com.oa.ht.mapper.ContractConditionMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author maimeng-mdp code-gen
 * @since 2023年10月8日
 */
@Service
public class ContractConditionService extends BaseService<ContractConditionMapper, ContractCondition> {
    static Logger logger = LoggerFactory.getLogger(ContractConditionService.class);

    /**
     * 自定义查询，支持多表关联
     *
     * @param page 分页条件
     * @param ew   一定要，并且必须加@Param("ew")注解
     * @param ext  如果xml中需要根据某些值进行特殊处理，可以通过这个进行传递，非必须，注解也可以不加
     * @return
     */
    public List<Map<String, Object>> selectListMapByWhere(IPage page, QueryWrapper ew, Map<String, Object> ext) {
        return baseMapper.selectListMapByWhere(page, ew, ext);
    }

    @Autowired
    ContractLogService contractLogService;

    public List<ContractCondition> selectConditionByIds(Map<String, Object> query) {
        return baseMapper.selectConditionByIds(query);
    }


    public ContractCondition getConditionByPaymentId(String paymentId) {
        return baseMapper.getConditionByPaymentId(paymentId);
    }

    public ContractCondition getConditionByReceiveId(String receiveId) {
        return baseMapper.getConditionByReceiveId(receiveId);
    }

    /**
     * 获取该条件下的已收款金额，不包括审核中的收款金额
     *
     * @param conditionId
     * @return
     */
    public BigDecimal getFinishReceiveAmountByConditionId(String conditionId) {
        return baseMapper.getFinishReceiveAmountByConditionId(conditionId);
    }

    /**
     * 获取该条件下已付款金额，不包括审核中的付款
     *
     * @param conditionId
     * @return
     */
    public BigDecimal getFinishPayAmountByConditionId(String conditionId) {
        return baseMapper.getFinishPayAmountByConditionId(conditionId);
    }

    /**
     * 获取该条件下收款金额，包括审核中的收款
     *
     * @param conditionId
     * @return
     */
    public BigDecimal getAllReceiveAmountByConditionId(String conditionId) {
        return baseMapper.getAllReceiveAmountByConditionId(conditionId);
    }

    public void updateRequirePaymentAmountByConditionId(String conditionId) {
        baseMapper.updateRequirePaymentAmountByConditionId(conditionId);
    }

    public void updateRequireReceiveAmountByConditionId(String conditionId) {
        baseMapper.updateRequireReceiveAmountByConditionId(conditionId);
    }

    /**
     * 获取该条件下已付款金额，包括审核中的付款
     *
     * @param conditionId
     * @return
     */
    public BigDecimal getAllPayAmountByConditionId(String conditionId) {
        return baseMapper.getAllPayAmountByConditionIdz(conditionId);
    }

    /**
     * 更新条件完成的付款金额及状态
     *
     * @param contractConditionDb
     */
    public void updateContractConditionPayFinishAmountAndStatus(ContractCondition contractConditionDb) {
        BigDecimal amount = this.getFinishPayAmountByConditionId(contractConditionDb.getConditionId());
        if (amount != null) {
            if (amount.compareTo(contractConditionDb.getConditionAmount()) >= 0) {
                ContractCondition update = new ContractCondition(contractConditionDb.getConditionId());
                update.setConditionStatus("2");
                update.setFinishAmount(amount);
                update.setFinishDate(new Date());
                this.updateSomeFieldByPk(update);
            } else {
                ContractCondition update = new ContractCondition(contractConditionDb.getConditionId());
                update.setConditionStatus("1");
                update.setFinishAmount(amount);
                this.updateSomeFieldByPk(update);
            }
        }

    }

    /**
     * 更新条件完成的收款金额及状态
     *
     * @param contractConditionDb
     */
    public void updateContractConditionReceiveFinishAmountAndStatus(ContractCondition contractConditionDb) {
        BigDecimal amount = this.getFinishReceiveAmountByConditionId(contractConditionDb.getConditionId());
        if (amount != null) {
            if (amount.compareTo(contractConditionDb.getConditionAmount()) >= 0) {
                ContractCondition update = new ContractCondition(contractConditionDb.getConditionId());
                update.setConditionStatus("2");
                update.setFinishAmount(amount);
                update.setFinishDate(new Date());
                this.updateSomeFieldByPk(update);
            } else {
                ContractCondition update = new ContractCondition(contractConditionDb.getConditionId());
                update.setConditionStatus("1");
                update.setFinishAmount(amount);
                this.updateSomeFieldByPk(update);
            }
        }

    }

    /**
     * 批量新增、修改、删除一体化
     */

    @Transactional
    public void batchSave(ContractConditionBatchVo contractConditionsVo) {
        User user = LoginUtils.getCurrentUserInfo();
        String htId = contractConditionsVo.getHtId();
        ContractCondition contractCondition = new ContractCondition();
        contractCondition.setHtId(htId);
        if (contractConditionsVo.getContractConditions() == null || contractConditionsVo.getContractConditions().size() == 0) {
            this.deleteByWhere(contractCondition);
            contractLogService.addLog(htId, user.getUserid(), user.getUsername(), "清空所有收付款条件");
            return;
        }
        List<ContractCondition> contractConditionsDb = this.selectListByWhere(contractCondition);

        if (contractConditionsDb == null || contractConditionsDb.size() == 0) {
            for (ContractCondition condition : contractConditionsVo.getContractConditions()) {
                condition.setConditionId(this.createKey("id"));
                condition.setHtId(htId);
            }
            this.batchInsert(contractConditionsVo.getContractConditions());
            contractLogService.addLog(htId, user.getUserid(), user.getUsername(), "新增" + contractConditionsVo.getContractConditions().size() + "条收付款条件");

            return;
        }


        Map<String, ContractCondition> dbMap = new HashMap<>();
        Map<String, ContractCondition> voMap = new HashMap<>();
        List<ContractCondition> addList = new ArrayList<>();
        List<ContractCondition> updateList = new ArrayList<>();
        List<ContractCondition> delList = new ArrayList<>();

        for (ContractCondition condition : contractConditionsDb) {
            dbMap.put(condition.getConditionId(), condition);
        }

        for (ContractCondition condition : contractConditionsVo.getContractConditions()) {
            voMap.put(condition.getConditionId(), condition);
        }


        for (ContractCondition condition : contractConditionsDb) {
            if (voMap.containsKey(condition.getConditionId())) {
                updateList.add(voMap.get(condition.getConditionId()));
            } else {
                delList.add(condition);
            }
        }

        for (ContractCondition condition : contractConditionsVo.getContractConditions()) {
            if (StringUtils.hasText(condition.getConditionId())) {
                if (!dbMap.containsKey(condition.getConditionId())) {
                    condition.setHtId(htId);
                    addList.add(condition);

                }
            } else {
                condition.setConditionId(this.createKey("id"));
                condition.setHtId(htId);
                addList.add(condition);
            }

        }

        if (delList.size() > 0) {
            this.batchDelete(delList);
            contractLogService.addLog(htId, user.getUserid(), user.getUsername(), "删除" + delList.size() + "条收付款条件");

        }

        if (addList.size() > 0) {
            this.batchInsert(addList);
            contractLogService.addLog(htId, user.getUserid(), user.getUsername(), "新增" + addList.size() + "条收付款条件");

        }

        if (updateList.size() > 0) {
            this.batchUpdate(updateList);
            contractLogService.addLog(htId, user.getUserid(), user.getUsername(), "修改" + updateList.size() + "条收付款条件");

        }

    }

}

